﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using InkFx.WinControl.Core;
using DA = InkFx.WinControl.XIDEAlignment;
using DTGS = InkFx.WinControl.XIDETabGroupState;

namespace InkFx.WinControl
{
    [ToolboxItem(false)]
    public class XIDEPopPanel : Panel
    {
        private XIDEPopPanel(XIDEPanel idePanel, XIDETabGroupPage page)
        {
            //SetStyle(Win32API.ControlStylesUAORSD, true);
            base.DoubleBuffered = true;

            var group = page.ParentGroup;
            this.TagForm = idePanel.FindForm();
            this.IDEPanel = idePanel;
            this.IDETabGroup = group;
            this.IDETabPage = page;
            this.Alignment = group.Alignment;
            this.ParentControl = group.Parent;

            if (TagForm != null)
            {
                TagForm.LocationChanged += ResetRect;
                TagForm.VisibleChanged += ResetRect;
            }
            if (IDEPanel != null)
            {
                IDEPanel.LocationChanged += ResetRect;
                IDEPanel.SizeChanged += ResetRect;
            }


            var align = this.Alignment;
            var padding = new Padding(0, 0, 0, 0);
            if (align == XIDEAlignment.Left) padding = new Padding(0, 0, SPLIT_SIZE, 0);
            else if (align == XIDEAlignment.Right) padding = new Padding(SPLIT_SIZE, 0, 0, 0);
            else if (align == XIDEAlignment.Top) padding = new Padding(0, 0, 0, SPLIT_SIZE);
            else if (align == XIDEAlignment.Bottom) padding = new Padding(0, SPLIT_SIZE, 0, 0);
            base.Padding = padding;
        }

        public static XIDEPopPanel ActivePopPanel = null;
        public static void TogglePopGroup(XIDETabGroupPage page)
        {
            bool same = false;
            var activePanel = ActivePopPanel;
            if (activePanel != null)
            {
                same = activePanel.IDETabPage == page;
                var activeGroup = activePanel.IDETabGroup;
                if (activeGroup.State == DTGS.Popup) activeGroup.State = DTGS.Collapse;
                activeGroup.PopupPage = null;
                activeGroup.Parent = activePanel.ParentControl;
                activePanel.Dispose();
                ActivePopPanel = null;
                if (same) return;
            }

            var group = page == null ? null : page.ParentGroup;
            var idePanel = group == null ? null : group.IDEPanel;
            if (idePanel == null) return;
            XIDEPopPanel panel = new XIDEPopPanel(idePanel, page);
            panel.Parent = idePanel;
            panel.BringToFront();
            panel.ResetRect(panel, EventArgs.Empty);
            ActivePopPanel = panel;

            group.PopupPage = page;
            group.SetSelectedPage(page);
            group.Parent = panel;
            group.State = DTGS.Popup;
            group.Focus();
        }



        private const int SPLIT_SIZE = 3;
        public System.Windows.Forms.Form TagForm { get; private set; }
        public XIDEPanel IDEPanel { get; private set; }
        public XIDETabGroup IDETabGroup { get; private set; }
        public XIDETabGroupPage IDETabPage { get; private set; }
        public XIDEAlignment Alignment { get; private set; }
        public System.Windows.Forms.Control ParentControl { get; private set; }

        public Rectangle RectSplitter { get; private set; }
        public Rectangle RectMovingSplitter { get; private set; }


        public bool IsSplitMoving { get; set; }


        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            DrawSplitter();
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            
            
            var align = this.Alignment;
            
            //if (IsSplitMoving)
            //    SetCursor((align == IDEAlignment.Top || align == IDEAlignment.Bottom) ? Cursors.HSplit : Cursors.VSplit);
            //else
            //    SetCursor(RectSplitter.Contains(e.Location) ? ((align == IDEAlignment.Top || align == IDEAlignment.Bottom) ? Cursors.HSplit : Cursors.VSplit) : Cursors.Default);
            //DoMove(e.Location);
            //m_MoveStartPoint = e.Location;
            //DrawSplitHelper();
            //this.Invalidate();
            //return;


            if (IsSplitMoving)
            {
                SetCursor((align == XIDEAlignment.Top || align == XIDEAlignment.Bottom) ? Cursors.HSplit : Cursors.VSplit);

                Rectangle rect = RectSplitter;
                Point point = e.Location;
                Point diff = new Point(m_MoveStartPoint.X - point.X, m_MoveStartPoint.Y - point.Y);
                if (align == XIDEAlignment.Top) this.RectMovingSplitter = new Rectangle(rect.X, rect.Y - diff.Y, rect.Width, rect.Height);
                else if (align == XIDEAlignment.Bottom) this.RectMovingSplitter = new Rectangle(rect.X, rect.Y - diff.Y, rect.Width, rect.Height);
                else if (align == XIDEAlignment.Left) this.RectMovingSplitter = new Rectangle(rect.X - diff.X, rect.Y, rect.Width, rect.Height);
                else if (align == XIDEAlignment.Right) this.RectMovingSplitter = new Rectangle(rect.X - diff.X, rect.Y, rect.Width, rect.Height);
                DrawSplitter();
            }
            else
                SetCursor(RectSplitter.Contains(e.Location) ? ((align == XIDEAlignment.Top || align == XIDEAlignment.Bottom) ? Cursors.HSplit : Cursors.VSplit) : Cursors.Default);

            this.Invalidate(false);
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            SetCursor(Cursors.Default);
        }

        private Point m_MoveStartPoint = Point.Empty;
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            IsSplitMoving = RectSplitter.Contains(e.Location);
            m_MoveStartPoint = e.Location;
            //this.Invalidate();
            DrawSplitter();
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            DoMove(e.Location);
            IsSplitMoving = false;
            EndSplitter();
        }


        protected Cursor m_BakCursor = null;
        protected void SetCursor(System.Windows.Forms.Cursor cursor)
        {
            if (m_BakCursor == null) m_BakCursor = base.Cursor ?? Cursors.Default;
            var baseCursor = base.Cursor;
            if (baseCursor != null && baseCursor != cursor)
                base.Cursor = cursor ?? m_BakCursor;
        }
        protected Rectangle GetRectSplitter()
        {
            return IsSplitMoving ? RectMovingSplitter : RectSplitter;
        }

        private void DrawSplitter()
        {
            if (!IsSplitMoving) return;
            Rectangle rectangle = GetRectSplitter();  //RectSplitter; //
            //Win32API.DrawSplitHelper(this.Handle, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height));
            
            Rectangle rectangle2 = this.RectangleToClient(this.RectangleToScreen(rectangle));
            //rectangle.Location = new Point(rectangle.X - this.Location.X, rectangle.Y - this.Location.Y);
            //Win32API.DrawSplitHelper(IDEPanel.Handle, rectangle2);
            //IDEPanel.Refresh();
            DrawSplitter(rectangle);  //rectangle2

            //Win32API.DrawSplitHelper(this.Handle, rectangle);

        }

        private void DoMove(Point point)
        {
            if (IsSplitMoving)
            {
                Point diff = new Point(m_MoveStartPoint.X - point.X, m_MoveStartPoint.Y - point.Y);

                var align = this.Alignment;
                if (align == XIDEAlignment.Top) this.Height = this.Height - diff.Y;
                else if (align == XIDEAlignment.Bottom) this.Height = this.Height + diff.Y;
                else if (align == XIDEAlignment.Left) this.Width = this.Width - diff.X;
                else if (align == XIDEAlignment.Right) this.Width = this.Width + diff.X;

                ResetRect(this, EventArgs.Empty);
            }
        }
        private void ResetRect(object sender, EventArgs e)
        {
            //var rect = IDEPanel.RectangleToScreen(new Rectangle(Point.Empty, IDEPanel.Size));
            //rect.Location = new Point(0, 0);
            var align = this.Alignment;
            var rect = IDEPanel.RectIDEInner;
            var dockWidth = rect.Width;
            var dockHeight = rect.Height;


            int width = this.Width;
            int height = this.Height;
            if (align == XIDEAlignment.Left)
            {
                this.Location = new Point(rect.X + 0, rect.Y + 0);
                this.Size = new Size(width, dockHeight);
                this.RectSplitter = new Rectangle(this.Width - SPLIT_SIZE, 0, SPLIT_SIZE, this.Height);
            }
            else if (align == XIDEAlignment.Right)
            {
                this.Location = new Point(rect.X + (dockWidth - width), rect.Y + 0);
                this.Size = new Size(width, dockHeight);
                this.RectSplitter = new Rectangle(0, 0, SPLIT_SIZE, this.Height);
            }
            else if (align == XIDEAlignment.Top)
            {
                this.Location = new Point(rect.X + 0, rect.Y + 0);
                this.Size = new Size(dockWidth, height);
                this.RectSplitter = new Rectangle(0, this.Height - SPLIT_SIZE, this.Width, SPLIT_SIZE);
            }
            else if (align == XIDEAlignment.Bottom)
            {
                this.Location = new Point(rect.X + 0, rect.Y + (dockHeight - height));
                this.Size = new Size(dockWidth, height);
                this.RectSplitter = new Rectangle(0, 0, this.Width, SPLIT_SIZE);
            }
        }





        public SplitterForm splitter;
        public void DrawSplitter(Rectangle rect)
        {
            try
            {
                ////m_DrawingSplitter = true;
                //m_RectSplitter = rect;
                //Win32API.DrawSplitHelper(this.Handle, m_RectSplitter);
                ////this.Invalidate(RectIDEInner, true);
                //this.Invalidate(rect, true);
                ////this.Update();

                ////this.Refresh();

                if (splitter == null)
                {
                    splitter = SplitterForm.BeginSplitter(this.FindForm(), Rectangle.Empty, this.RectangleToScreen(rect)); //todo: 这里的 Rectangle.Empty 需要调整
                }

                splitter.ShowSplitter(this.RectangleToScreen(rect));
            }
            finally { /*m_DrawingSplitter = false;*/ }
        }
        public void EndSplitter()
        {
            if (splitter != null)
            {
                splitter.EndSplitter();
                splitter = null;
            }
        }

    }
}
